package com.linln.admin.app.service.task;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.linln.admin.app.constants.AppConstants;
import com.linln.admin.app.constants.TaskTypeEnum;
import com.linln.admin.app.domain.AppInfo;
import com.linln.admin.app.domain.AppVersion;
import com.linln.admin.app.domain.RepoAccount;
import com.linln.admin.app.domain.VersionApp;
import com.linln.admin.app.service.branch.BranchHelper;
import com.linln.admin.system.domain.TaskQueue;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * 创建开发分支
 */
@Service
@Slf4j
public class CreateDevBranchTask extends AbstractTaskExecutor {
    /**
     * 是否可以处理这个任务
     *
     * @param t
     * @return
     */
    @Override
    public boolean support(TaskQueue t) {
        return t != null && TaskTypeEnum.CREATE_DEV_BRANCH.getType().equals(t.getType());
    }

    /**
     * 处理任务，并返回处理结果
     *
     * @param t
     * @return true-成功; 其它-false
     */
    @Override
    public boolean exec(TaskQueue t) {
        Long versionId = t.getRelate_id();
        Optional<AppVersion> ver = versionRepository.findById(versionId);
        if (!ver.isPresent()) {
            throw new IllegalArgumentException("对应的版本信息不存在！");
        }
        AppVersion version = ver.get();
        List<VersionApp> vas = versionAppRepository.findByVersionId(versionId);
        if (vas == null) {
            vas = new ArrayList<>();//保证向下执行时不会出空指针
        }

        //当关联的应用为空时，可能是清空了所有应用，这时候就要将所有的应用删除掉
        String baseVer = version.getVersion().trim().replace(" ", "");
        if (baseVer.startsWith(AppConstants.BRANCH_DEV_PREFIX)) {
            baseVer = baseVer.substring(4);
        }

        String tarVersionName = AppConstants.BRANCH_DEV_PREFIX + baseVer;
        if (AppConstants.YES.equals(version.getHotfix_flag())) {
            tarVersionName = AppConstants.BRANCH_HOTFIX_PREFIX + baseVer;
        }

        for (VersionApp va : vas) {
            if (va == null || va.getApp_id() == null) {
                continue;
            }
            if (AppConstants.YES.equals(va.getHas_dev())) {
                continue;//如果已经有开发分支，则不处理
            }
            Optional<AppInfo> app = infoRepository.findById(va.getApp_id());
            if (!app.isPresent()) {
                versionAppRepository.delete(va);
                continue;
            }

            try {
                AppInfo info = app.get();
                RepoAccount account = getRepoAccount(info.getRepo_account_id());
                if (BranchHelper.findHandler(info.getRepo_type()).createNewBranch(baseVer, info.getRepo_url(), account.getAccount(), account.getPass(), info.getBase(), tarVersionName)) {
                    va.setHas_dev(AppConstants.YES);
                } else {
                    va.setHas_dev(AppConstants.NO);
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            versionAppRepository.save(va);
        }
        //删除已经放弃的分支
        deleteBranch(t, version, baseVer);
        return true;
    }

    private void deleteBranch(TaskQueue t, AppVersion version, String baseVer) {
        List<Long> deletedAppIds = null;
        try {
            String json = t.getData();
            deletedAppIds = new ObjectMapper().readValue(json, new TypeReference<List<Long>>() {
            });
        } catch (Exception e) {
            log.warn(t.getData() + " parseJSON:" + e.getMessage(), e);
        }
        if (deletedAppIds == null || deletedAppIds.isEmpty()) {
            return;
        }
        String dev = AppConstants.BRANCH_DEV_PREFIX + baseVer;
        String release = "";
        if (AppConstants.YES.equals(version.getHotfix_flag())) {
            dev = AppConstants.BRANCH_HOTFIX_PREFIX + baseVer;
        } else if (AppConstants.YES.equals(version.getCo_release_branch())) {
            release = AppConstants.BRANCH_RELEASE_PREFIX + baseVer;
        }
        for (Long appId : deletedAppIds) {
            try {
                Optional<AppInfo> app = infoRepository.findById(appId);
                if (!app.isPresent()) {
                    continue;
                }
                AppInfo info = app.get();
                RepoAccount account = getRepoAccount(info.getRepo_account_id());
                BranchHelper.findHandler(info.getRepo_type()).deleteBranch(baseVer, info.getRepo_url(), account.getAccount(), account.getPass(), dev);
                if (StringUtils.isNotBlank(release)) {
                    BranchHelper.findHandler(info.getRepo_type()).deleteBranch(baseVer, info.getRepo_url(), account.getAccount(), account.getPass(), release);
                }
            } catch (Exception e) {
                log.warn(e.getMessage(), e);
            }
        }
    }
}
